﻿using System;
using System.Collections;
using System.Collections.Generic;
using DavidJalbert.TinyCarControllerAdvance;
using LogSystem;
using UnityEngine;
using UnityEngine.Serialization;
using Yoozoo.Gameplay.Liberty.AI;
using Yoozoo.Gameplay.Liberty.StreetEvent;
using Yoozoo.Gameplay.Liberty.VehicleController;
using Yoozoo.Gta.Common;
using Yoozoo.Mars.Got;
using AnimationState = Yoozoo.Gameplay.Liberty.AI.AnimationState;

namespace Yoozoo.Gameplay.Liberty.PlayerController
{

    public enum CarDoorDirection
    {
        LeftCarDoor = 1,
        RightCarDoor = 2,
    }

    public enum CarEnterMode
    {
        Empty_Left = 1,
        Empty_Right = 2,
        LeftNpc_Left = 3,
        LeftNpc_Right = 4,
        RightNpc_Left = 5,
        RightNpc_Right = 6,
    }

    // 主角进出车辆的状态
    [Flags]
    public enum EnterExitCarState
    {
        None = 0,
        
        ReadyNav2Door = 1,          // 准备导航到车门
        
        CarEntityFreeze = 1 << 2,   // 冻结被抢车辆
        
        Navigating = 1<<4,          // 开始导航
        NavComplete = 1<<8,
        BeginEnterCar = 1<<12,
        EnterCarComplete = 1<<16,
        
        BeginExitCar = 1<<17,
        
        ExitCarComplete = 1<<31,
    }
    
    public class RigidBodySetting
    {
        public float angularDrag;
        public float mass;
        public float drag;
        public bool useGravity;
        public bool isKinematic;
        public RigidbodyInterpolation interpolation;
        public CollisionDetectionMode collisionDetectionMode;
        public RigidbodyConstraints constraints;
    }

    [Serializable]
    public class SwitchCarDoorTime
    {
        [Range(0,5)]
        public float enter_openDoorDelayTime = 0.2f;
        [Range(0,6)]
        public float enter_closeDoorDelayTime = 3f;
        [Range(0,6)]
        public float enter_carDriveModeTime = 2f;
        [Range(0,6)]
        public float enter_carComplete = 1.2f;
    }

    [Serializable]
    public class GrabNpcBehaviors
    {
        [Range(0,4)]
        public float expelAnimDelayTime = 0.1f;
        [Range(0,8)]
        public float escapeDelayTime = 4f;
        
        public string animName;
        
        [Range(0,6)]
        public float openCarLeftDoorTime = 3;
        [Range(0,10)]
        public float closeCarLeftDoorTime = 5;
    }
    
    [RequireComponent(typeof(PlayerControlModeMgr))]
    [RequireComponent(typeof(PlayerVehicleController))]
    public class PlayerVehicleBehaviourMgr : MonoBehaviour
    {
        private PlayerControlModeMgr _playerControlModeMgr;
        private PlayerVehicleController _vehicleController;
        private AISeeker _playerSeeker;
        private AIData _playerData;
        private LocomotionAgent _locomotionAgent;
        private PlayerInputCamera _playerInputCamera;
        private Animator _playerAnimator;
        
        public CarEntity carEntity;
        public CarDoorDirection nav2DoorDirection;
        
        private Transform _carTransform;
        private VehicleSetting _vehicleSetting;

        private Transform _doorPoint;
        private Vector3 _lastDoorPos;
        private bool _nav2DoorStatus = false;
        private CarDoorDirection _doorDirection;
        private Coroutine _enterCarItor;
        private Coroutine _exitCarItor;
        private Coroutine _enterCarDoor;
        private Coroutine _enterCarNpc;
        private Coroutine _exitCarDoor;
        private RigidBodySetting _rigidBodySetting;

        
        [FormerlySerializedAs("_enterExitCarState")] 
        public EnterExitCarState enterExitCarState = EnterExitCarState.None;

        public bool canGrabCar = false;

        // [Range(0,5)]
        // public float enter_openLeftDoorDelayTime = 0.2f;
        // [Range(0,6)]
        // public float enter_closeLeftDoorDelayTime = 3f;
        // [Range(0,5)]
        // public float enter_openRightDoorDelayTime = 0.2f;
        // [Range(0,6)]
        // public float enter_closeRightDoorDelayTime = 3f;

        // 开关车门的延迟时间 
        public SwitchCarDoorTime emptyCar_Left_DoorTime;
        public SwitchCarDoorTime leftNpcCar_Left_DoorTime;
        public SwitchCarDoorTime emptyCar_Right_DoorTime;
        public SwitchCarDoorTime leftNpcCar_Right_DoorTime;
        
        [Range(0,2)]
        public float exit_openLeftDoorDelayTime = 0.2f;
        [Range(0,6)]
        public float exit_colseLeftDoorDelayTime = 3f;
        [Range(0,2)]
        public float closeDoorSoundDelayTime = 0.5f;
        
        // 主驾驶npc数据
        //public GrabNpcBehaviors emptyCar_Left_GrabNpc;
        public GrabNpcBehaviors leftNpcCar_Left_GrabNpc;
        //public GrabNpcBehaviors emptyCar_Right_GrabNpc;
        public GrabNpcBehaviors leftNpcCar_Right_GrabNpc;

        public float vehicleBoxColliderOffset = 0.45f;
        
        // 记录上车前的武器ID
        private int _enterCarWeaponId = 0;
        
        // // Debug 参数
        // private Vector3 debugVehiclePos;
        // private Vector3 debugVehicleRot;
        // private string vehicleAssetName;

        public void ClickDoor()
        {
            // 开关门
            _playerData = _playerControlModeMgr.playerEntity.AIEntity.data;
            
            if (enterExitCarState == EnterExitCarState.None)
            {
                if (_playerData.animationState == AnimationState.Idle ||
                    _playerData.animationState == AnimationState.Locomotion ||
                    _playerData.animationState == AnimationState.Sprinting ||
                    _playerData.animationState == AnimationState.DodgeSprint)
                {
                    if (carEntity)
                    {
                        SetCarEntity(carEntity);
                        Nav2Door(nav2DoorDirection);
                    }
                }
                return;
            }
            
            StartExitCar();
        }

        public void StartExitCar()
        {
            if (enterExitCarState == EnterExitCarState.EnterCarComplete)
            {
                if (_exitCarItor!=null)
                {
                    StopCoroutine(_exitCarItor);
                }
                
                _playerData.npcStatus = NpcStatus.ExitCar;
                _exitCarItor = StartCoroutine(ExitCar());
                enterExitCarState = EnterExitCarState.BeginExitCar;
            }
        }

        public void BreakNav2Door()
        {
            if (enterExitCarState == EnterExitCarState.Navigating || enterExitCarState == EnterExitCarState.NavComplete||
                enterExitCarState == EnterExitCarState.CarEntityFreeze)
            {
                LeaveCar();
            }
        }

        private void LeaveCar()
        {
            if (_enterCarItor != null)
            {
                StopCoroutine(_enterCarItor);
            }

            _playerControlModeMgr.inputController.playInput.verNavValue = 0;
            _playerControlModeMgr.inputController.playInput.horNavValue = 0;

            _playerControlModeMgr.viewAvatar.inputRootMotion.enabled = true;
            _playerControlModeMgr.viewAvatar.locomotionAgent.enabled = false;

            canGrabCar = false;
            SwitchPlayerCarEntityCollision(carEntity, false);

            if (_playerControlModeMgr.playerModel.gameObject.GetComponent<Rigidbody>() == null)
            {
                var rigid = _playerControlModeMgr.playerModel.gameObject.AddComponent<Rigidbody>();
                _playerControlModeMgr.viewAvatar.rigidbody = rigid;
                _playerControlModeMgr.inputController.rigidBody = rigid;
                rigid.mass = _rigidBodySetting.mass;
                rigid.drag = _rigidBodySetting.drag;
                rigid.angularDrag = _rigidBodySetting.angularDrag;
                rigid.useGravity = _rigidBodySetting.useGravity;
                rigid.isKinematic = _rigidBodySetting.isKinematic;
                rigid.interpolation = _rigidBodySetting.interpolation;
                rigid.collisionDetectionMode = _rigidBodySetting.collisionDetectionMode;
                rigid.constraints = _rigidBodySetting.constraints;

                BoxCollider carCollider = carEntity.carController.getRigidbody().GetComponent<BoxCollider>();
                carCollider.size = new Vector3(carCollider.size.x, carCollider.size.y + vehicleBoxColliderOffset,
                    carCollider.size.z);
            }

            _playerControlModeMgr.viewAvatar.controllerCollider.enabled = true;

            // 切换到玩家输入模式
            _playerControlModeMgr.Switch2InputMode();
            _playerData.npcStatus = NpcStatus.None;
            _nav2DoorStatus = false;
            var viewRoot = _playerControlModeMgr.viewAvatar.transform.parent;
            viewRoot.SetParent(_playerControlModeMgr.transform);
            // 相机切换到玩家输入模式
            _vehicleSetting.isPlayerControl = false;
            _vehicleSetting.playerCamera = null;
            _playerControlModeMgr.Set2InputCamera();
            _playerInputCamera.CameraInputMode = CameraInputMode.Player;
            _playerControlModeMgr.SwitchNavParameter(AutoNavParameters.AutoNavType.Normal);

            _playerControlModeMgr.inputCamera.ControlMode = CameraControlMode.Follow;
            _playerControlModeMgr.inputController.playInput.CloseCameraInput = false;
            _playerControlModeMgr.inputController.playInput.CloseMoveInput = false;
            _playerControlModeMgr.viewAvatar.inputRootMotion.enabled = true;

            _playerControlModeMgr.playerEntity.AIEntity.viewer.animationAgent.SetDisableOperate(false);
            _playerControlModeMgr.playerEntity.AIEntity.viewer.animator.updateMode = AnimatorUpdateMode.Normal;
            // 装上武器
            _playerControlModeMgr.playerEntity.AIEntity.battleAgent.ChangeWeapon(_enterCarWeaponId);
            _playerControlModeMgr.inputController.playInput.CloseCameraInput = false;
            _playerControlModeMgr.inputController.playInput.CloseMoveInput = false;
            if (_playerInputCamera.ignoreList.Contains(carEntity.transform))
            {
                _playerInputCamera.ignoreList.Remove(carEntity.transform);
            }

            if (carEntity)
            {
                if (carEntity.npcLeft != null)
                {
                    // 车上的主角不能销毁
                    if (carEntity.npcLeft.id != -1)
                    {
                        LibertyAIUtils.AIManager.RemoveNpc(carEntity.npcLeft.id);
                    }
                }

                carEntity.carController.getRigidbody().constraints = RigidbodyConstraints.None;
                carEntity.carController.setHandbrake(true);

                carEntity.carController.getRigidbody().constraints = RigidbodyConstraints.FreezeAll;
                carEntity.carController.setWheelsEnabled(false);


                carEntity.carController.getRigidbody().constraints = RigidbodyConstraints.None;

                carEntity.audioComponent.loopAdjustToneSound.SetSoundValue(0);
                carEntity.audioComponent.loopAdjustToneSound.enabled = false;
                carEntity.audioComponent.loopAdjustToneSound.StopSound(carEntity.audioComponent.engineSound);
                if (_playerInputCamera && _playerInputCamera.ignoreList.Contains(carEntity.transform))
                {
                    _playerInputCamera.ignoreList.Remove(carEntity.transform);
                }

                carEntity.InteriorComponent.HideInteriors();
                carEntity.data.carStyle = CarStyle.None;
            }

            enterExitCarState = EnterExitCarState.None;
        }
        
        private void Awake()
        {
            _playerControlModeMgr = GetComponent<PlayerControlModeMgr>();
            _vehicleController = GetComponent<PlayerVehicleController>();
        }

        private float _refreshUITime;
        
        private void Update()
        {
            bool refreshUI = false;
            _refreshUITime += Time.deltaTime;
            if (_refreshUITime > 2)
            {
                refreshUI = true;
                _refreshUITime = 0;
            }

            Vector3 playerPos = _playerControlModeMgr.playerModel.transform.position;
            
            // 每帧检测可以抢夺的车辆，必须在侧边，旁边没有阻挡物
            if (enterExitCarState == EnterExitCarState.None)
            {
                var carEntities = 
                    LibertyAIUtils.AIManager.CarBirthManager.carEntities;

                bool exist = false;
                foreach (var ce in carEntities)
                {
                    CarEntity entity = ce.Value;
                    float roll = entity.carController.transform.rotation.eulerAngles.z;
                    if (Mathf.Abs(roll) > 15)
                    {
                        // 有倾斜的，不允许玩家上车
                        continue;
                    }
                    
                    Vector4 bound = entity.vehicleSetting.GetBound();

                    if (playerPos.x > bound.x && playerPos.x < bound.y 
                        && playerPos.z > bound.z && playerPos.z < bound.w)
                    {
                        carEntity = entity;
                        exist = true;
                        break;
                    }
                }

                if (!exist)
                {
                    carEntity = null;
                }
                
                // 得到可抢夺车门的方向
                if (carEntity)
                {
                    if (!canGrabCar || refreshUI)
                    {
                        ResidentHandler.Inst.GetFunction("CityLuaFunction.OnSwitchGrabCarBtn").Action(true);
                    }

                    nav2DoorDirection = CarDoorDirection.LeftCarDoor;
                    if (Vector3.Distance(playerPos,carEntity.vehicleSetting.leftDoorOpenPoint.position) >
                        Vector3.Distance(playerPos,carEntity.vehicleSetting.rightDoorOpenPoint.position))
                    {
                        nav2DoorDirection = CarDoorDirection.RightCarDoor;
                    }
                    canGrabCar = true;
                }
                else
                {
                    if (canGrabCar || refreshUI)
                    {
                        ResidentHandler.Inst.GetFunction("CityLuaFunction.OnSwitchGrabCarBtn").Action(false);
                    }
                    canGrabCar = false;
                }
            }
            _playerData = _playerControlModeMgr.playerEntity.AIEntity.data;
            
            if (_playerData != null && _playerData.npcStatus == NpcStatus.InCar)
            {
                // TODO 临时容错
                var viewRoot = _playerControlModeMgr.viewAvatar.transform.parent;
                viewRoot.localPosition = Vector3.zero;
                viewRoot.localEulerAngles = Vector3.zero;
            }
            
            // // 已经在寻路到车门时的一些处理
            // if (_nav2DoorStatus && (_playerData.npcStatus & NpcStatus.InCar) == 0 && (_playerData.npcStatus & NpcStatus.ExitCar) == 0 )
            // {
            //     // 车辆在运动时需要反复调用寻路接口，追随车辆
            //     if (Vector3.Distance(_doorPoint.position,_lastDoorPos) > 0.5f)
            //     {
            //         if (_enterCarItor!=null)
            //         {
            //             StopCoroutine(_enterCarItor);
            //         }
            //         _playerControlModeMgr.SetPlayerDestination(_doorPoint.position);  // 这里进入到了 AutoNav模式
            //         _enterCarItor = StartCoroutine(EnterCar(_doorPoint.position, _doorPoint.rotation,_doorDirection));
            //         _lastDoorPos = _doorPoint.position;
            //     }
            //     
            //     // TODO 车辆的在玩家朝向的方向速度大于一定值时，车辆可以逃离
            //     
            //     // TODO 如果在导航过程中车辆长时间被物体阻挡时，取消抢车逻辑
            // }
            //
            // DEBUG

        }
        

        public void SetCarEntity(CarEntity entity)
        {
            carEntity = entity;
            _vehicleSetting = carEntity.vehicleSetting;
            _carTransform = carEntity.carController.getRigidbody().transform;
        }

        public void Nav2Door(CarDoorDirection doorDirection)
        {
            enterExitCarState = EnterExitCarState.ReadyNav2Door;

            _playerSeeker = _playerControlModeMgr.playerEntity.AIEntity.seeker;
            _playerData = _playerControlModeMgr.playerEntity.AIEntity.data;
            _locomotionAgent = _playerControlModeMgr.playerAgent;
            _playerInputCamera = _playerControlModeMgr.inputCamera;
            _playerAnimator = _playerControlModeMgr.viewAvatar.animator;

            _doorDirection = doorDirection;
            Transform door = _vehicleSetting.leftDoorOpenPoint;
            if (doorDirection == CarDoorDirection.RightCarDoor)
            {
                door = _vehicleSetting.rightDoorOpenPoint;
            }
            
           
            _doorPoint = door;
            _lastDoorPos = _doorPoint.position;
            _nav2DoorStatus = true;
            _enterCarItor = StartCoroutine(EnterCar(_doorPoint,_doorDirection));
        }

        private bool GetBoardSidePoint(Transform door,out Vector3 sidePoint)
        {
            sidePoint = Vector3.zero;
            if (!carEntity)
            {
                return false;
            }

            float distance = Vector3.Distance(door.position, _playerControlModeMgr.Position);
            Vector3 direction = (door.position - _playerControlModeMgr.Position).normalized;

            if (Physics.Raycast(_playerControlModeMgr.Position +
                                new Vector3(0,0.3f,0) +
                                _playerControlModeMgr.Forward * 0.25f, direction, out var hitInfo, distance))
            {
                if (hitInfo.collider == carEntity.collider)
                {
                    sidePoint = carEntity.carController.GetBoardSideWheelsDistance(carEntity,_playerControlModeMgr.Position);
                    
                    return true;
                }
            }
            return false;
        }
         
        IEnumerator EnterCar(Transform door,CarDoorDirection doorDirection)
        {
            ResidentHandler.Inst.GetFunction("CityLuaFunction.OnSwitchGrabCarBtn").Action(false);
            yield return null;
            // 关闭车辆AI操纵
            //carEntity.vehicleAI.Active = false;
            carEntity.carController.applyHandbrake = true;
            carEntity.vehicleAI.splineModeData.applyHandbrake = true;
            carEntity.data.carStatus = CarStatus.PlayerControl;
            _playerInputCamera.ignoreList.Add(carEntity.transform);
            SwitchPlayerCarEntityCollision(carEntity, true);
            yield return new WaitWhile(() =>
            {
                carEntity.carController.setMotor(0);
                carEntity.carController.setSteering(0);
                carEntity.carController.applyHandbrake = true;
                carEntity.vehicleAI.splineModeData.applyHandbrake = true;
                return Mathf.Abs(carEntity.carController.getForwardVelocity()) > 0.5f;
            });
            carEntity.carController.getRigidbody().constraints = RigidbodyConstraints.FreezeAll;
            enterExitCarState = EnterExitCarState.CarEntityFreeze;
            carEntity.vehicleAI.Active = false;
            // 启用车辆轮胎
            carEntity.carController.setWheelsEnabled(true);
            // 开启车辆NavMeshCut
            if (carEntity.navmeshCut)
            {
                carEntity.navmeshCut.enabled = true;
            }
            
            carEntity.carController.setPosition(carEntity.carController.getRigidbody().transform.position);
            carEntity.carController.setRotation(Quaternion.LookRotation(carEntity.carController.getRigidbody().transform.forward));
            carEntity.carController.reset(true);
            carEntity.carController.immobilize(true);
            
            carEntity.SetPlayerParameters();
            _playerControlModeMgr.SwitchNavParameter(AutoNavParameters.AutoNavType.RobCar);
            _playerControlModeMgr.viewAvatar.inputRootMotion.enabled = false;
            // TODO 如果玩家是在车辆的前方、后方，而不是侧面，需要先走到侧边。
            if (GetBoardSidePoint(door,out Vector3 sidePoint))
            {
#if UNITY_EDITOR
                Debug.DrawLine(sidePoint,sidePoint + Vector3.up * 10,Color.green,10);
#endif
                // bool front = Vector3.Dot(_playerControlModeMgr.Forward, sidePoint) > 0;
                // float verValue = front ? 1 : -1;
                // Vector3 f = front ? _playerControlModeMgr.Forward : -_playerControlModeMgr.Forward;
                // float horValue = ((sidePoint - _playerControlModeMgr.Position).normalized - f.normalized).magnitude;

                // verValue *= 0.2f;
                // horValue *= 0.2f;
                //
                // _playerControlModeMgr.inputController.playInput.verNavValue = verValue;
                // _playerControlModeMgr.inputController.playInput.horNavValue = horValue;

                var s = ((sidePoint - _playerControlModeMgr.Position)).normalized;
                s =  _playerInputCamera.transform.InverseTransformDirection(s).normalized;
                float horValue = s.x;
                float verValue = s.z;
                
                verValue *= 0.2f;
                horValue *= 0.2f;
                _playerControlModeMgr.inputController.playInput.verNavValue = verValue;
                _playerControlModeMgr.inputController.playInput.horNavValue = horValue;
                
                enterExitCarState = EnterExitCarState.Navigating;

                float tt = 0;
                yield return new WaitWhile(() =>
                {
                    tt += Time.deltaTime;
                    return tt < 0.2f;
                });
                
                // 重新判断从哪边上车
                Vector3 playerPos = _playerControlModeMgr.playerModel.transform.position;
                nav2DoorDirection = CarDoorDirection.LeftCarDoor;
                if (Vector3.Distance(playerPos,carEntity.vehicleSetting.leftDoorOpenPoint.position) >
                    Vector3.Distance(playerPos,carEntity.vehicleSetting.rightDoorOpenPoint.position))
                {
                    nav2DoorDirection = CarDoorDirection.RightCarDoor;
                }
                doorDirection = nav2DoorDirection;
                door = _vehicleSetting.leftDoorOpenPoint;
                if (doorDirection == CarDoorDirection.RightCarDoor)
                {
                    door = _vehicleSetting.rightDoorOpenPoint;
                }
            }
            
            _playerControlModeMgr.inputController.playInput.verNavValue = 0;
            _playerControlModeMgr.inputController.playInput.horNavValue = 0;
            _playerControlModeMgr.viewAvatar.locomotionAgent.enabled = true;
            _playerControlModeMgr.SetPlayerDestination(door.position, NavType.Nav2Car);  // 这里进入到了 AutoNav模式
            int brf = _playerControlModeMgr.viewAvatar.locomotionAgent.banRotationFrame;
            _playerControlModeMgr.viewAvatar.locomotionAgent.banRotationFrame = 5;
            enterExitCarState = EnterExitCarState.Navigating;
            float faultTimestamp = Time.time;
            Vector3 faultPos = _playerSeeker.transform.position;
            // 寻路到达目的地了
            yield return new WaitWhile(() =>
            {
                Vector3 curPos = _playerSeeker.transform.position;
                bool isReached = (_playerSeeker.ReachedEndOfPath()
                                  || Vector3.Distance(door.position, curPos)<=0.5f);

                if ((Time.time-faultTimestamp)>0.5f && !isReached)
                {
                    float ERROR_DISTANCE = 0.1f;
                    Vector2 offset2D = new Vector2(curPos.x - faultPos.x, curPos.z - faultPos.z);
                    if (offset2D.magnitude < ERROR_DISTANCE)
                    {
                        // 寻路失败，重新寻路
                        faultTimestamp = Time.time;
                        _playerControlModeMgr.SetPlayerDestination(door.position, NavType.Nav2Car);  // 这里进入到了 AutoNav模式
                    }
                }
                
                return !isReached;
            });
            _playerControlModeMgr.viewAvatar.locomotionAgent.banRotationFrame = brf;
            yield return null;
            enterExitCarState = EnterExitCarState.NavComplete;
            BoxCollider carCollider = carEntity.carController.getRigidbody().GetComponent<BoxCollider>();
            carCollider.size = new Vector3(carCollider.size.x, carCollider.size.y - vehicleBoxColliderOffset, carCollider.size.z);
            // 关闭车辆NavMeshCut
            if (carEntity.navmeshCut)
            {
                carEntity.navmeshCut.enabled = false;
            }
            // 销毁刚体
            var rigid = _playerControlModeMgr.viewAvatar.rigidbody;
            _rigidBodySetting = new RigidBodySetting()
            {
                mass = rigid.mass,
                drag = rigid.drag,
                angularDrag = rigid.angularDrag,
                useGravity = rigid.useGravity,
                isKinematic = rigid.isKinematic,
                interpolation = rigid.interpolation,
                collisionDetectionMode =  rigid.collisionDetectionMode,
                constraints = rigid.constraints,
            };
            GameObject.DestroyImmediate(rigid);
            _playerControlModeMgr.viewAvatar.controllerCollider.enabled = false;
            _playerSeeker.Stop();
            // 调整角色方向和位置
            // _playerControlModeMgr.NavPlayerTransmission(door.position,door.rotation.eulerAngles);
            yield return null;
            _playerData.npcStatus = NpcStatus.EnterCar;  // 一定要播放上车动画的时候再设置状态，否则位置旋转会不一致
            _playerControlModeMgr.NavPlayerTransmission(door.position,door.rotation.eulerAngles);
            // 显示内饰
            carEntity.InteriorComponent.ShowInteriors();
            carEntity.EnablePassenger();
            carEntity.data.driveNpcId = 0; // npc id归零
            //
             yield return new WaitForSeconds(Time.fixedDeltaTime * 4);
            // 将玩家ViewRoot设置为车辆的子物体
            var viewRoot = _playerControlModeMgr.viewAvatar.transform.parent;
            viewRoot.SetParent(carEntity.vehicleSetting.leftSeatPoint);
            _playerControlModeMgr.Switch2DriveCarMode(carEntity);  // 进入到驾驶车辆模式
            yield return null;
            
            ResidentHandler.Inst.GetFunction("CityLuaFunction.OnEnterCarDriveMode").Action();
            
            // _playerAnimator.ResetTrigger("walk");
            yield return null;
            
            enterExitCarState = EnterExitCarState.BeginEnterCar;
            CarEnterMode enterMode = CarEnterMode.Empty_Left;
            SwitchCarDoorTime carDoorTime = null;
            GrabNpcBehaviors grabNpcBehaviors = null;
            // 开始播放开门动画
            _playerControlModeMgr.playerEntity.AIEntity.viewer.animationAgent.SetDisableOperate(true);
            // 卸下武器
            _enterCarWeaponId = _playerControlModeMgr.playerEntity.AIEntity.WeaponSystem.SelectedWeaponId;
            _playerControlModeMgr.playerEntity.AIEntity.battleAgent.ChangeWeapon(101);
            _playerControlModeMgr.playerEntity.AIEntity.viewer.animator.updateMode = AnimatorUpdateMode.AnimatePhysics;
            // _playerControlModeMgr.NavPlayerTransmission(door.position,door.rotation.eulerAngles);
            yield return new WaitForEndOfFrame();
            if (doorDirection == CarDoorDirection.LeftCarDoor)
            {
                if (carEntity.npcLeft == null && carEntity.npcRight == null)
                {
                     enterMode = CarEnterMode.Empty_Left;
                     carDoorTime = emptyCar_Left_DoorTime;
                     //grabNpcBehaviors = emptyCar_Left_GrabNpc;
                     _playerAnimator.CrossFade("VehicleStateMachine.OpenCarLeftDoorMode01",0.01f,0,0);
                }
                else if (carEntity.npcLeft != null && carEntity.npcRight == null)
                {
                     enterMode = CarEnterMode.LeftNpc_Left;
                     carDoorTime = leftNpcCar_Left_DoorTime;
                     grabNpcBehaviors = leftNpcCar_Left_GrabNpc;
                     _playerAnimator.CrossFade("VehicleStateMachine.OpenCarLeftDoorMode02",0.01f,0,0);
                }
                else if (carEntity.npcLeft != null && carEntity.npcRight != null)
                {
                     _playerAnimator.CrossFade("VehicleStateMachine.OpenCarLeftDoorMode03",0.01f,0,0);
                }
            }
            else if (doorDirection == CarDoorDirection.RightCarDoor)
            {
                if (carEntity.npcLeft == null && carEntity.npcRight == null)
                {
                    enterMode = CarEnterMode.Empty_Right;
                    carDoorTime = emptyCar_Right_DoorTime;
                    //grabNpcBehaviors = emptyCar_Right_GrabNpc;
                    _playerAnimator.CrossFade("VehicleStateMachine.OpenCarRightDoorMode01",0.01f,0,0f);
                }
                else if (carEntity.npcLeft != null && carEntity.npcRight == null)
                {
                    enterMode = CarEnterMode.LeftNpc_Right;
                    carDoorTime = leftNpcCar_Right_DoorTime;
                    grabNpcBehaviors = leftNpcCar_Right_GrabNpc;
                    _playerAnimator.CrossFade("VehicleStateMachine.OpenCarRightDoorMode02",0.1f,0,0);
                }
                else if (carEntity.npcLeft != null && carEntity.npcRight != null)
                {
                    _playerAnimator.CrossFade("VehicleStateMachine.OpenCarRightDoorMode03",0.01f,0,0);
                }
            }
            _enterCarDoor = StartCoroutine(EnterCarDoorBehavior(doorDirection,carDoorTime));
            if (grabNpcBehaviors != null)
            {
                _enterCarNpc = StartCoroutine(EnterCarNpcBehavior(doorDirection,carEntity.npcLeft,carEntity,grabNpcBehaviors));
                if (doorDirection == CarDoorDirection.RightCarDoor)
                {
                    _exitCarDoor = StartCoroutine(ExitCarDoorBehavior(grabNpcBehaviors.openCarLeftDoorTime,grabNpcBehaviors.closeCarLeftDoorTime));
                }
            }
            
            // 摄像机切换到车辆模式
            _vehicleSetting.isPlayerControl = true;
            _vehicleSetting.playerCamera = _playerInputCamera;
            _vehicleSetting.Set2InputCamera();
            
            _playerInputCamera.CameraInputMode = CameraInputMode.Car;
            
            // 关闭角色碰撞组件
            _playerSeeker.gameObject.SetActive(false);
            
            yield return new WaitForSeconds(carDoorTime.enter_carDriveModeTime);
            
            // 玩家和车辆进入驾驶模式
            //yield return new WaitForSeconds(0.1f);
            carEntity.audioComponent.loopAdjustToneSound.SetSoundValue(0);
            carEntity.audioComponent.loopAdjustToneSound.enabled = true;
            carEntity.audioComponent.loopAdjustToneSound.PlaySound(carEntity.audioComponent.engineSound);
            
            yield return new WaitForSeconds(carDoorTime.enter_carComplete);
            // _playerControlModeMgr.playerEntity.AIEntity.viewer.animationAgent.SetDisableOperate(false);
            _playerControlModeMgr.playerEntity.AIEntity.viewer.animator.updateMode = AnimatorUpdateMode.Normal;
            _playerInputCamera.ControlMode = CameraControlMode.Follow;
            carEntity.data.carStatus = CarStatus.PlayerControl;
            _vehicleController.SetCarEntity(carEntity);
            carEntity.carController.getRigidbody().constraints = RigidbodyConstraints.None;
            carEntity.carController.setHandbrake(false);
            _vehicleController.active = true;
            
            _playerControlModeMgr.viewAvatar.locomotionAgent.enabled = false;
            _playerData.npcStatus = NpcStatus.InCar;
            carEntity.npcLeft = _playerControlModeMgr.playerEntity.AIEntity;
            enterExitCarState = EnterExitCarState.EnterCarComplete;
            
            var rm = StreetEventManager.GetInstance().vehicleRacingManager;
            if (rm!=null)
            {
                rm.playerVehicle = carEntity;
            }
        }


        public void EnterCarImmediately(CarEntity entity,bool needResetController = false)
        {
            _playerSeeker = _playerControlModeMgr.playerEntity.AIEntity.seeker;
            _playerData = _playerControlModeMgr.playerEntity.AIEntity.data;
            _locomotionAgent = _playerControlModeMgr.playerAgent;
            _playerInputCamera = _playerControlModeMgr.inputCamera;
            _playerAnimator = _playerControlModeMgr.viewAvatar.animator;
            
            SetCarEntity(entity);
            carEntity.vehicleAI.Active = false;
            _playerInputCamera.ignoreList.Add(carEntity.transform);
            
            Timers.inst.Add(0.1f,1,(o =>
            {
                carEntity.carController.setWheelsEnabled(true);
                
                BoxCollider carCollider = carEntity.carController.getBoxCollider();
                carCollider.size = new Vector3(carCollider.size.x, carCollider.size.y - vehicleBoxColliderOffset, carCollider.size.z);
                var pos = carEntity.carController.getRigidbody().transform.position;
                pos.y = 0.01f;
                carEntity.carController.setPosition(pos);
                carEntity.carController.setRotation(Quaternion.LookRotation(carEntity.carController.getRigidbody().transform.forward));
                
                if (needResetController)
                {
                    carEntity.carController.setLocalPosition(Vector3.zero);
                    carEntity.carController.setLocalRotation(Quaternion.identity);
                }
                
                _playerInputCamera.ResetCamera();
            }));

            carEntity.SetPlayerParameters();
            if (carEntity.InteriorComponent.enabled)
            {
                carEntity.InteriorComponent.ShowInteriors();
            }
            

            // 销毁刚体
            var rigid = _playerControlModeMgr.viewAvatar.rigidbody;
            if (rigid)
            {
                _rigidBodySetting = new RigidBodySetting()
                {
                    mass = rigid.mass,
                    drag = rigid.drag,
                    angularDrag = rigid.angularDrag,
                    useGravity = rigid.useGravity,
                    isKinematic = rigid.isKinematic,
                    interpolation = rigid.interpolation,
                    collisionDetectionMode =  rigid.collisionDetectionMode,
                    constraints = rigid.constraints,
                };
                GameObject.DestroyImmediate(rigid);
            }
            _playerControlModeMgr.viewAvatar.controllerCollider.enabled = false;

            // 将玩家ViewRoot设置为车辆的子物体
            var viewRoot = _playerControlModeMgr.viewAvatar.transform.parent;
            viewRoot.SetParent(carEntity.vehicleSetting.leftSeatPoint);
            _playerControlModeMgr.Switch2DriveCarMode(carEntity);  // 进入到驾驶车辆模式
            viewRoot.localPosition = Vector3.zero;
            viewRoot.localEulerAngles = Vector3.zero;
            _playerControlModeMgr.playerModel.localPosition = Vector3.zero;
            _playerControlModeMgr.playerModel.localEulerAngles = Vector3.zero;
            
            ResidentHandler.Inst.GetFunction("CityLuaFunction.OnEnterCarDriveMode").Action();

            // 摄像机切换到车辆模式
            _vehicleSetting.isPlayerControl = true;
            _vehicleSetting.playerCamera = _playerInputCamera;
            _vehicleSetting.Set2InputCamera();

            _playerInputCamera.CameraInputMode = CameraInputMode.Car;

            // 关闭角色碰撞组件
            _playerSeeker.gameObject.SetActive(false);

            // 玩家和车辆进入驾驶模式
            carEntity.audioComponent.loopAdjustToneSound.SetSoundValue(0);
            carEntity.audioComponent.loopAdjustToneSound.enabled = true;
            carEntity.audioComponent.loopAdjustToneSound.PlaySound(carEntity.audioComponent.engineSound);

            _playerInputCamera.ControlMode = CameraControlMode.Follow;
            carEntity.data.carStatus = CarStatus.PlayerControl;
            _vehicleController.SetCarEntity(carEntity);
            carEntity.carController.getRigidbody().constraints = RigidbodyConstraints.None;
            carEntity.carController.getRigidbody().useGravity = true;
            carEntity.carController.getRigidbody().isKinematic = false;
            carEntity.carController.setHandbrake(false);
            _vehicleController.active = true;
            
            _playerControlModeMgr.viewAvatar.locomotionAgent.enabled = false;
            _playerControlModeMgr.viewAvatar.inputRootMotion.enabled = false;
            _playerData.npcStatus = NpcStatus.InCar;
            carEntity.npcLeft = _playerControlModeMgr.playerEntity.AIEntity;
            enterExitCarState = EnterExitCarState.EnterCarComplete;

            _playerControlModeMgr.playerEntity.AIEntity.viewer.animationAgent.SetDisableOperate(true);
            // 卸下武器
            _enterCarWeaponId = _playerControlModeMgr.playerEntity.AIEntity.WeaponSystem.SelectedWeaponId;
            _playerControlModeMgr.playerEntity.AIEntity.battleAgent.ChangeWeapon(101);
            _playerAnimator.Play("VehicleStateMachine.a_male_car_Drive_Idle");
            _playerInputCamera.ResetCamera();
            _playerInputCamera.transform.localEulerAngles = new Vector3(_playerInputCamera.transform.localEulerAngles.x,
                0, _playerInputCamera.transform.localEulerAngles.z);

            var rm = StreetEventManager.GetInstance().vehicleRacingManager;
            if (rm!=null)
            {
                rm.playerVehicle = carEntity;
            }
        }
        

        IEnumerator EnterCarDoorBehavior(CarDoorDirection doorDirection,SwitchCarDoorTime doorTime)
        {
            if (doorDirection == CarDoorDirection.LeftCarDoor)
            {
                Animator doorAnimator = carEntity.vehicleSetting.leftDoorAnimator;

                yield return new WaitForSeconds(doorTime.enter_openDoorDelayTime);
                doorAnimator.Play("leftDoorOpen");
                carEntity.audioComponent.PlayVoice(carEntity.audioComponent.openDoorSound);
                
                yield return new WaitForSeconds(doorTime.enter_closeDoorDelayTime);
                doorAnimator.Play("leftDoorClose");
                yield return new WaitForSeconds(closeDoorSoundDelayTime);
                carEntity.audioComponent.PlayVoice(carEntity.audioComponent.closeDoorSound);
            }
            else if (doorDirection == CarDoorDirection.RightCarDoor)
            {
                Animator doorAnimator = carEntity.vehicleSetting.rightDoorAnimator;
            
                yield return new WaitForSeconds(doorTime.enter_openDoorDelayTime);
                doorAnimator.Play("rightDoorOpen");
                carEntity.audioComponent.PlayVoice(carEntity.audioComponent.openDoorSound);
            
                yield return new WaitForSeconds(doorTime.enter_closeDoorDelayTime);
                doorAnimator.Play("rightDoorClose");
                yield return new WaitForSeconds(closeDoorSoundDelayTime);
                carEntity.audioComponent.PlayVoice(carEntity.audioComponent.closeDoorSound);
            }
            yield break;
        }

        IEnumerator EnterCarNpcBehavior(CarDoorDirection doorDirection,AIEntity npc, CarEntity car, GrabNpcBehaviors grabNpcBehaviors)
        {
            npc.viewer.locomotionAgent.SetCarEntity(car.carBase);
            npc.viewer.animationAgent.SetDisableOperate(true);
            
            yield return new WaitForSeconds(grabNpcBehaviors.expelAnimDelayTime);
            var npcViewer = npc.viewer.transform.parent;
            npc.viewer.viewerRoot.position = npcViewer.position;
            npc.viewer.viewerRoot.rotation = npcViewer.rotation;
            npcViewer.SetParent(npc.viewer.viewerRoot);
            npcViewer.localPosition = Vector3.zero;
            npcViewer.localEulerAngles = Vector3.zero;
            npc.viewer.locomotionAgent.enabled = true;
            npc.viewer.locomotionAgent.SetRelative();
            npc.onHitCollider.gameObject.SetActive(true);
            npc.headCollider.gameObject.SetActive(true);
            npc.data.npcStatus = NpcStatus.ExpelCar;
            carEntity.npcLeft = null;
            npc.viewer.animator.CrossFade(grabNpcBehaviors.animName,0.01f,0);

            yield return new WaitForSeconds(grabNpcBehaviors.escapeDelayTime);
            Debug.Log(LogModule.LibertyScene,"切换车辆Npc状态");
            npc.viewer.animationAgent.SetDisableOperate(false);
            var np = npc.viewer.locomotionAgent.transform.position;
            var nr = npc.viewer.locomotionAgent.transform.eulerAngles;
            if (npc.seeker)
            {
                npc.seeker.transform.position = np;
                npc.seeker.transform.eulerAngles = nr;
                npc.data.position = np;
                npc.data.CurrentLerpRotation = nr;
                npc.characterController.enabled = true;
                npc.seeker.transform.gameObject.SetActive(true);
                npc.data.npcStyle = NpcStyle.PathWalker;        // 转变成可以寻路的角色
                npc.data.npcStatus = NpcStatus.Escape;
            }
        }

        public void ExitCarImmediately(bool needRecycle = false)
        {
            if (_enterCarDoor != null)
            {
                StopCoroutine(_enterCarDoor);
                _enterCarDoor = null;
            }

            if (_enterCarDoor != null)
            {
                StopCoroutine(_enterCarNpc);
                _enterCarNpc = null;
            }

            if (_enterCarDoor != null)
            {
                StopCoroutine(_exitCarDoor);
                _exitCarDoor = null;
            }

            LeaveCar();
            if (needRecycle)
            {
                LibertyAIUtils.AIManager.CarBirthManager.RemoveCar(carEntity.id);
            }
        }
        
        IEnumerator ExitCar()
        {
            _playerControlModeMgr.viewAvatar.locomotionAgent.enabled = true;
            _playerControlModeMgr.viewAvatar.locomotionAgent.SetRelative();
            yield return null;
            carEntity.npcLeft = null;
            
            carEntity.carController.getRigidbody().constraints = RigidbodyConstraints.None;
            _vehicleController.active = false;
            _vehicleController.ClearCarEntity();

            carEntity.carController.setHandbrake(true);

            yield return new WaitWhile(() =>
            {
                return Mathf.Abs(carEntity.carController.getForwardVelocity()) > 0.5f;
            });
            carEntity.carController.getRigidbody().constraints = RigidbodyConstraints.FreezeAll;
            carEntity.carController.setWheelsEnabled(false);
          

            BoxCollider carCollider = carEntity.carController.getRigidbody().GetComponent<BoxCollider>();
            carCollider.size = new Vector3(carCollider.size.x, carCollider.size.y + vehicleBoxColliderOffset, carCollider.size.z);
            
            // 判断出门点是否有效
            carEntity.audioComponent.loopAdjustToneSound.SetSoundValue(0);
            carEntity.audioComponent.loopAdjustToneSound.enabled = false;
            carEntity.audioComponent.loopAdjustToneSound.StopSound(carEntity.audioComponent.engineSound);
            
            StartCoroutine(ExitCarDoorBehavior(exit_openLeftDoorDelayTime,exit_colseLeftDoorDelayTime));
            yield return new WaitForSeconds(0.5f);
            
            // _playerControlModeMgr.playerEntity.AIEntity.viewer.animationAgent.SetDisableOperate(true);
            _playerControlModeMgr.playerEntity.AIEntity.viewer.animator.updateMode = AnimatorUpdateMode.AnimatePhysics;
            _playerAnimator.CrossFade("VehicleStateMachine.ExitCar",0.1f,0,0);
            yield return new WaitForSeconds(4.6f);
            _playerControlModeMgr.ClearCarEntity();

            // 重新添加刚体
            var rigid = _playerControlModeMgr.playerModel.gameObject.AddComponent<Rigidbody>();
            _playerControlModeMgr.viewAvatar.rigidbody = rigid;
            _playerControlModeMgr.inputController.rigidBody = rigid;
            rigid.mass = _rigidBodySetting.mass;
            rigid.drag = _rigidBodySetting.drag;
            rigid.angularDrag = _rigidBodySetting.angularDrag;
            rigid.useGravity = _rigidBodySetting.useGravity;
            rigid.isKinematic = _rigidBodySetting.isKinematic;
            rigid.interpolation = _rigidBodySetting.interpolation;
            rigid.collisionDetectionMode = _rigidBodySetting.collisionDetectionMode;
            rigid.constraints = _rigidBodySetting.constraints;
            _playerControlModeMgr.viewAvatar.controllerCollider.enabled = true;

            // 切换到玩家输入模式
            _playerControlModeMgr.Switch2InputMode();
            _playerData.npcStatus = NpcStatus.None;
            _nav2DoorStatus = false;
            var viewRoot = _playerControlModeMgr.viewAvatar.transform.parent;
            viewRoot.SetParent(_playerControlModeMgr.transform);

            ResidentHandler.Inst.GetFunction("CityLuaFunction.OnExitCarDriveMode").Action();

            // 相机切换到玩家输入模式
            _vehicleSetting.isPlayerControl = false;
            _vehicleSetting.playerCamera = null;
            _playerControlModeMgr.Set2InputCamera();
            _playerInputCamera.CameraInputMode = CameraInputMode.Player;
            yield return new WaitForSeconds(1.5f);
            _playerControlModeMgr.SwitchNavParameter(AutoNavParameters.AutoNavType.Normal);

            enterExitCarState = EnterExitCarState.ExitCarComplete;
            yield return null;
            enterExitCarState = EnterExitCarState.None;
            carEntity.carController.getRigidbody().constraints = RigidbodyConstraints.None;
            _playerControlModeMgr.viewAvatar.inputRootMotion.enabled = true;
            _playerControlModeMgr.playerEntity.AIEntity.viewer.animationAgent.SetDisableOperate(false);
            _playerControlModeMgr.playerEntity.AIEntity.viewer.animator.updateMode = AnimatorUpdateMode.Normal;
            // 装上武器
            _playerControlModeMgr.playerEntity.AIEntity.battleAgent.ChangeWeapon(_enterCarWeaponId);
            canGrabCar = false;
            SwitchPlayerCarEntityCollision(carEntity, false);
            
            _playerControlModeMgr.inputController.playInput.CloseCameraInput = false;
            _playerControlModeMgr.inputController.playInput.CloseMoveInput = false;
            if (_playerInputCamera.ignoreList.Contains(carEntity.transform))
            {
                _playerInputCamera.ignoreList.Remove(carEntity.transform);
            }
            
            carEntity.InteriorComponent.HideInteriors();
            carEntity.data.carStyle = CarStyle.None;
        }

        IEnumerator ExitCarDoorBehavior(float openTime,float closeTime)
        {
            var doorAnimator = carEntity.vehicleSetting.leftDoorAnimator;
            yield return new WaitForSeconds(openTime);
            if (doorAnimator)
            {
                doorAnimator.Play("leftDoorOpen");
                carEntity.audioComponent.PlayVoice(carEntity.audioComponent.openDoorSound);
                
                yield return new WaitForSeconds(closeTime);
                doorAnimator.Play("leftDoorClose");
                yield return new WaitForSeconds(closeDoorSoundDelayTime);
                carEntity.audioComponent.PlayVoice(carEntity.audioComponent.closeDoorSound);
            }
          
        }

        
        
        
        public void SwitchPlayerCarEntityCollision(CarEntity ce,bool ignore)
        {
            if (ce != null)
            {
                if (_playerControlModeMgr.characterCtrl)
                {
                    ce.carController.ignoreWheelsCollision(_playerControlModeMgr.characterCtrl,ignore);
                }
            }
        }

        private void OnDisable()
        {
            canGrabCar = false;
        }
    }
}